package com.wlyuan.index.remote.store;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author yuanjie
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class MessageStore {
    private final RedissonClient redissonClient;
    private RMapCache<String, List<String>> messageMap;

    @PostConstruct
    public void initialize() {
        this.messageMap = redissonClient.getMapCache("PC::CACHE::INDEX::MESSAGE");
    }

    public void add(Class<?> messageClass, String messageString) {
        this.addAsync(messageClass.getName(), messageString);
    }

    public Collection<String> list(Class<?> messageClass) {
        return this.messageMap.getOrDefault(messageClass.getName(), Collections.emptyList());
    }

    private void add(String messageClass, String messageString) {
        try {
            var messageStrings = this.messageMap.get(messageClass);
            if (null == messageStrings) {
                messageStrings = new ArrayList<>();
            }
            messageStrings.add(messageString);
            if (messageStrings.size() > 100) {
                messageStrings = new ArrayList<>(messageStrings.subList(messageStrings.size() - 50, messageStrings.size()));
            }
            this.messageMap.fastPut(messageClass, messageStrings);
        } catch (Exception e) {
            logger.error("Store message error: {} {}", messageClass, messageString, e);
        }
    }

    private void addAsync(String messageClass, String messageString) {
        try {
            CompletableFuture.runAsync(() -> this.add(messageClass, messageString));
        } catch (Exception e) {
            logger.error("Store message error: {} {}", messageClass, messageString, e);
        }
    }
}
